package org.gdstash.ui.table;

import org.gdstash.file.DDSLoader;
import org.gdstash.item.GDItem;
import org.gdstash.ui.GDStashFrame;
import org.gdstash.util.GDImagePool;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class GDItemCollectionTableModel extends DefaultTableModel {
    public static final int FILTER_ALL = 1;
    public static final int FILTER_FOUND = 2;
    public static final int FILTER_MISSING = 3;
    public static final Color GREEN_BG;
    public static final Color RED_BG;
    private List<GDItemInfo> data;
    private GDItemCollectionRow[] rowsAll;
    private GDItemCollectionRow[] rows;

    public GDItemCollectionTableModel(final List<GDItemInfo> data) {
        this.data = data;
        this.adjustUI();
    }

    public void adjustUI() {
        GDItemCollectionRow.updateColumnNames();
        this.setColumnIdentifiers(GDItemCollectionRow.columnNames);
        this.setData(this.data);
    }

    public void setData(final List<GDItemInfo> data) {
        this.data = data;
        this.rowsAll = null;
        this.rows = null;
        if (data == null) {
            return;
        }
        final int size = data.size();
        this.rowsAll = new GDItemCollectionRow[size];
        this.rows = new GDItemCollectionRow[size];
        final GDItem.LabelInfo liEmpty = new GDItem.LabelInfo();
        liEmpty.text = "";
        int i = 0;
        GDItem.LabelInfo li = null;
        for (final GDItemInfo item : data) {
            this.rowsAll[i] = new GDItemCollectionRow();
            this.rows[i] = this.rowsAll[i];
            BufferedImage img = item.gdItem.getImage();
            this.rowsAll[i].item = item;
            this.rows[i].baseName = item.gdItem.getBaseName();
            if (img != null) {
                if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
                    final int w = img.getWidth() * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
                    final int h = img.getHeight() * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
                    img = DDSLoader.getScaledImage(img, w, h);
                }
                this.rowsAll[i].icon = new ImageIcon(img);
            }
            li = item.gdItem.getCompleteNameInfo(false, true);
            if (li == null) {
                li = liEmpty;
            }
            this.rowsAll[i].name = li;
            li = item.gdItem.getRequiredLevelInfo();
            if (li == null) {
                li = liEmpty;
            }
            this.rowsAll[i].level = li;
            if (item.scCount == 0) {
                this.rowsAll[i].softcore = false;
                this.rowsAll[i].scIcon = GDImagePool.iconBtnCancel24;
            } else {
                this.rowsAll[i].softcore = true;
                this.rowsAll[i].scIcon = GDImagePool.iconBtnOk24;
            }
            if (item.hcCount == 0) {
                this.rowsAll[i].hardcore = false;
                this.rowsAll[i].hcIcon = GDImagePool.iconBtnCancel24;
            } else {
                this.rowsAll[i].hardcore = true;
                this.rowsAll[i].hcIcon = GDImagePool.iconBtnOk24;
            }
            ++i;
        }
        this.fireTableDataChanged();
    }

    @Override
    public int getRowCount() {
        if (this.rows == null) {
            return 0;
        }
        return this.rows.length;
    }

    @Override
    public int getColumnCount() {
        return GDItemCollectionRow.columnNames.length;
    }

    @Override
    public String getColumnName(final int column) {
        return GDItemCollectionRow.columnNames[column];
    }

    static {
        GREEN_BG = new Color(170, 255, 180);
        RED_BG = new Color(255, 180, 170);
    }

    @Override
    public boolean isCellEditable(final int row, final int column) {
        return false;
    }

    @Override
    public Object getValueAt(final int row, final int column) {
        if (this.rows == null) {
            return null;
        }
        if (row < 0) {
            return null;
        }
        if (row >= this.rows.length) {
            return null;
        }
        if (this.rows[row] == null) {
            return null;
        }
        if (column == 0) {
            return this.rows[row].icon;
        }
        if (column == 1) {
            return this.rows[row].name.text;
        }
        if (column == 2) {
            return this.rows[row].level.text;
        }
        if (column == 3) {
            return this.rows[row].scIcon;
        }
        if (column == 4) {
            return this.rows[row].hcIcon;
        }
        return null;
    }

    @Override
    public Class getColumnClass(final int column) {
        return GDItemCollectionRow.COLUMN_CLASSES[column];
    }

    @Override
    public void setValueAt(final Object value, final int row, final int column) {
        if (!this.isCellEditable(row, column)) {
            return;
        }
        if (this.rows == null) {
            return;
        }
        if (row < 0) {
            return;
        }
        if (row >= this.rows.length) {
            return;
        }
        if (this.rows[row] == null) {
            return;
        }
        if (column == 0) {
            this.rows[row].icon = (ImageIcon) value;
        }
        if (column == 1) {
            this.rows[row].name.text = (String) value;
        }
        if (column == 2) {
            this.rows[row].level.text = (String) value;
        }
        if (column == 3) {
            this.rows[row].scIcon = (ImageIcon) value;
        }
        if (column == 4) {
            this.rows[row].hcIcon = (ImageIcon) value;
        }
    }

    public String getCellText(final int row, final int column) {
        if (this.rows == null) {
            return "";
        }
        if (row < 0) {
            return "";
        }
        if (row >= this.rows.length) {
            return "";
        }
        if (this.rows[row] == null) {
            return "";
        }
        if (column == 1) {
            return this.rows[row].name.text;
        }
        if (column == 2) {
            return this.rows[row].level.text;
        }
        return "";
    }

    public Color getCellTextColor(final int row, final int column) {
        if (this.rows == null) {
            return Color.BLACK;
        }
        if (row < 0) {
            return Color.BLACK;
        }
        if (row >= this.rows.length) {
            return Color.BLACK;
        }
        if (this.rows[row] == null) {
            return Color.BLACK;
        }
        if (column == 1) {
            return this.rows[row].name.foreground;
        }
        if (column == 2) {
            return this.rows[row].level.foreground;
        }
        return Color.BLACK;
    }

    public Color getCellBackgroundColor(final int row, final int column) {
        if (this.rows == null) {
            return Color.WHITE;
        }
        if (row < 0) {
            return Color.WHITE;
        }
        if (row >= this.rows.length) {
            return Color.WHITE;
        }
        if (this.rows[row] == null) {
            return Color.WHITE;
        }
        if (column != 1 && column != 2) {
            return Color.WHITE;
        }
        if (this.rows[row].item.scCount > 0) {
            return GDItemCollectionTableModel.GREEN_BG;
        }
        if (this.rows[row].item.hcCount > 0) {
            return GDItemCollectionTableModel.GREEN_BG;
        }
        return GDItemCollectionTableModel.RED_BG;
    }

    public void filter(final int filter) {
        if (this.rowsAll == null) {
            return;
        }
        final GDItem.LabelInfo li = null;
        final GDItem.LabelInfo liEmpty = new GDItem.LabelInfo();
        liEmpty.text = "";
        int size = 0;
        for (int i = 0; i < this.rowsAll.length; ++i) {
            switch (filter) {
                case 1: {
                    ++size;
                    break;
                }
                case 2: {
                    if (this.rowsAll[i].item.scCount > 0 || this.rowsAll[i].item.hcCount > 0) {
                        ++size;
                        break;
                    }
                    break;
                }
                case 3: {
                    if (this.rowsAll[i].item.scCount == 0 && this.rowsAll[i].item.hcCount == 0) {
                        ++size;
                        break;
                    }
                    break;
                }
            }
        }
        if (size == 0) {
            this.rows = null;
        } else {
            this.rows = new GDItemCollectionRow[size];
            int pos = 0;
            for (int j = 0; j < this.rowsAll.length; ++j) {
                boolean addItem = false;
                switch (filter) {
                    case 1: {
                        addItem = true;
                        break;
                    }
                    case 2: {
                        if (this.rowsAll[j].item.scCount > 0 || this.rowsAll[j].item.hcCount > 0) {
                            addItem = true;
                            break;
                        }
                        break;
                    }
                    case 3: {
                        if (this.rowsAll[j].item.scCount == 0 && this.rowsAll[j].item.hcCount == 0) {
                            addItem = true;
                            break;
                        }
                        break;
                    }
                }
                if (addItem) {
                    this.rows[pos] = this.rowsAll[j];
                    ++pos;
                }
            }
        }
        this.fireTableDataChanged();
    }

    public void sort(final Comparator<GDItemCollectionRow> comp) {
        if (comp == null) {
            return;
        }
        if (this.rows == null) {
            return;
        }
        Arrays.<GDItemCollectionRow>sort(this.rows, comp);
    }

    public GDItemInfo getItem(final int row) {
        if (this.rows == null) {
            return null;
        }
        if (row < 0) {
            return null;
        }
        if (row >= this.rows.length) {
            return null;
        }
        if (this.rows[row] == null) {
            return null;
        }
        return this.rows[row].item;
    }
}
